#include <soar.h>

int main(int argc, char *argv[])
{
    char *public_key_file="rsa_public.pem";
    char *private_key_file="rsa_private.pem";
    char *private_key_passwd="c3por2d2";
    char public_key_pem[KB(1)];
    char private_key_pem[KB(4)];
    int res;
    FILE *fp;
    char msg[KB(1)];
    unsigned char enc[KB(10)];
    int enc_size;
    char plain[KB(1)];
    int plain_size;
    char buf[KB(1)];
    OSSL_KEY public_key, private_key;

    ossl_init();

    printf("*********************\n");
    printf("* Generate key pair *\n");
    printf("*********************\n");
    if((res=ossl_rsa_generate_key_pair(1024, private_key_passwd,
                   public_key_pem, private_key_pem)))
    {
        printf("ossl_rsa_generate_key_pair fail, res:%d\n", res);
        return(-1);
    }
    printf("%s\n%s\n", public_key_pem, private_key_pem);

    printf("**************************\n");
    printf("* Generate key pair file *\n");
    printf("**************************\n");
    if((res=ossl_rsa_generate_key_pair_file(1024, private_key_passwd,
                   public_key_file, private_key_file)))
    {
        printf("ossl_rsa_generate_key_pair_file fail, res:%d\n", res);
        return(-1);
    }
    printf("public key file: %s\nprivate key file: %s\n\n",
            public_key_file, private_key_file);

    if((fp=fopen(public_key_file, "r")) == NULL)
    {
        printf("rsa_public.pem not found\n");
        return(-1);
    }

    res=0;
    CLR_BUF(public_key_pem);
    while(fgets(msg, sizeof(msg), fp))
        strcat(public_key_pem, msg);
    fclose(fp);

    if((fp=fopen(private_key_file, "r")) == NULL)
    {
        printf("rsa_private.pem not found\n");
        return(-1);
    }
    res=0;
    CLR_BUF(private_key_pem);
    while(fgets(msg, sizeof(msg), fp))
        strcat(private_key_pem, msg);
    fclose(fp);

    printf("*******************\n");
    printf("* Load public key *\n");
    printf("*******************\n");
    if((res=ossl_rsa_load_public_key(public_key_pem, &public_key)))
    {
        printf("ossl_rsa_load_public_key fail, res:%d\n", res);
        return(-1);
    }
    ossl_rsa_free_key(public_key);
    printf("ossl_rsa_load_public_key succeed\n\n");

    printf("************************\n");
    printf("* Load public key file *\n");
    printf("************************\n");
    if((res=ossl_rsa_load_public_key_file(public_key_file,
                    &public_key)))
    {
        printf("ossl_rsa_load_public_key_file fail, res:%d\n", res);
        return(-1);
    }
    printf("ossl_rsa_load_public_key_file succeed\n\n");

    printf("********************\n");
    printf("* Load private key *\n");
    printf("********************\n");
    if((res=ossl_rsa_load_private_key(private_key_pem,
                    private_key_passwd, &private_key)))
    {
        printf("ossl_rsa_load_private_key fail, res:%d\n", res);
        return(-1);
    }
    ossl_rsa_free_key(private_key);
    printf("ossl_rsa_load_private_key succeed\n\n");

    printf("************************\n");
    printf("* Load private key file *\n");
    printf("************************\n");
    if((res=ossl_rsa_load_private_key_file(private_key_file,
                    private_key_passwd, &private_key)))
    {
        printf("ossl_rsa_load_private_key_file fail, res:%d\n", res);
        return(-1);
    }
    printf("ossl_rsa_load_private_key_file succeed\n\n");

    strcpy(msg, "少年听雨歌楼上，红烛昏罗帐。壮年听雨客舟中，江阔云低、断雁叫西风。而今听雨僧庐下，鬓已星星也。悲欢离合总无情，一任阶前点滴到天明。");
    printf("plain(%d): %s\n", strlen(msg), msg);
    printf("\n");

    printf("*********************\n");
    printf("* Encrypt & Decrypt *\n");
    printf("*********************\n");
    if((res=ossl_rsa_encrypt(public_key,
                    (unsigned char *)msg, strlen(msg),
                    (unsigned char *)enc, &enc_size)))
    {
        printf("ossl_rsa_encrypt fail, res:%d\n", res);
        return(-1);
    }
    printf("encrypt: %s\n", expand_to_str(enc, enc_size, buf));
    if((res=ossl_rsa_decrypt(private_key,
                    (unsigned char *)enc, enc_size,
                    (unsigned char *)plain, &plain_size)))
    {
        printf("ossl_rsa_decrypt fail, res:%d\n", res);
        return(-1);
    }
    printf("decrypt: succeed\n");
    printf("plain(%d): %s\n\n", strlen(plain), plain);

    printf("*****************\n");
    printf("* Sign & Verify *\n");
    printf("*****************\n");
    if((res=ossl_rsa_sign(private_key,
                    (unsigned char *)msg, strlen(msg),
                    (unsigned char *)enc, &enc_size)))
    {
        printf("ossl_rsa_sign fail, res:%d\n", res);
        return(-1);
    }
    printf("sign: %s\n", expand_to_str(enc, enc_size, buf));
    if((res=ossl_rsa_verify(public_key,
                    (unsigned char *)msg, strlen(msg),
                    (unsigned char *)enc, enc_size)))
    {
        printf("ossl_rsa_verify fail, res:%d\n", res);
        return(-1);
    }
    printf("verify: succeed\n\n");

    ossl_clean();

    return(0);
}
